home *** CD-ROM | disk | FTP | other *** search
/ IRIX Base Documentation 2002 November / SGI IRIX Base Documentation 2002 November.iso / usr / share / catman / a_man / cat7 / alp.z / alp
Encoding:
Text File  |  2002-10-03  |  23.2 KB  |  456 lines

  1.  
  2.  
  3.  
  4. aaaallllpppp((((7777))))                                                                  aaaallllpppp((((7777))))
  5.  
  6.  
  7.  
  8. NNNNAAAAMMMMEEEE
  9.      _aaaa_llll_pppp - algorithm pool management module
  10.  
  11. DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
  12.      The STREAMS module _aaaa_llll_pppp maintains a pool of algorithms (in the form of
  13.      STREAMS-compatible subroutines) that may be used for processing STREAMS
  14.      data messages.  Interfaces are defined allowing modules to request and
  15.      initiate processing by any of the algorithms maintained in the pool.  It
  16.      is expected to help centralize and standardize the interfaces to
  17.      algorithms that now represent a proliferation of similar-but-different
  18.      STREAMS modules.  Its major use is envisioned as a central registry of
  19.      available code set conversion algorithms or other types of common data-
  20.      manipulating routines.
  21.  
  22.      An _a_l_g_o_r_i_t_h_m _p_o_o_l is a registry (or _p_o_o_l) of available functions; in this
  23.      case, routines for performing transformations on STREAMS data messages.
  24.      Registered functions may keep information on attached users, which means
  25.      that algorithms need not be stateless, but may maintain extensive state
  26.      information related to each connection.  An algorithm from the pool is
  27.      called by another in-kernel module with arguments that are a STREAMS data
  28.      message and a unique identifier.  If a message is passed back to the
  29.      caller, it is the algorithm's output, otherwise the algorithm may store
  30.      partially convertible input until enough input is received to give back
  31.      output on a subsequent call.
  32.  
  33.      This pool is one means for providing a consistent and flexible interface
  34.      for _c_o_d_e _s_e_t _c_o_n_v_e_r_s_i_o_n within STREAMS modules, especially _kkkk_bbbb_dddd, but it
  35.      may also be used to provide other services that are commonly duplicated
  36.      by several modules.
  37.  
  38.      The _aaaa_llll_pppp module contains some subroutines dealing with its (minor) role as
  39.      a module, a data definition for an algorithm list, connection and
  40.      disconnection routines, and a search routine for finding registered
  41.      items. The module interface incorporated into _aaaa_llll_pppp serves the purpose of
  42.      providing an _iiii_oooo_cccc_tttt_llll interface, so that users can find out what algorithms
  43.      are registered [see _aaaa_llll_pppp_qqqq(1)].
  44.  
  45.      The programmer of a function for use with _aaaa_llll_pppp provides a simple module
  46.      with a simple specified interface.  The module must have an
  47.      initialization routine (_x_x_x_iiii_nnnn_iiii_tttt) which is called at system startup time
  48.      to register itself with _aaaa_llll_pppp, an open routine, and an interface routine
  49.      (which actually implements the algorithm).
  50.  
  51.      The registry method of dynamically building the list of available
  52.      functions obviates the need for recompiling modules or otherwise updating
  53.      a list or reconfiguring other parts of the system to accommodate
  54.      additions or deletions. To install a new function module, one merely
  55.      links it with the kernel in whatever manner is standard for that system;
  56.      there is no need for updating or re-configuring any other parts of the
  57.      kernel (including _aaaa_llll_pppp itself).  The remainder of this discussion concerns
  58.      the in-kernel operation and use of the module.
  59.  
  60.  
  61.  
  62.  
  63.                                                                         PPPPaaaaggggeeee 1111
  64.  
  65.  
  66.  
  67.  
  68.  
  69.  
  70. aaaallllpppp((((7777))))                                                                  aaaallllpppp((((7777))))
  71.  
  72.  
  73.  
  74.    CCCCaaaalllllllliiiinnnngggg SSSSeeeeqqqquuuueeeennnncccceeee
  75.      An algorithm is called from the pool by first requesting a connection via
  76.      the _aaaa_llll_pppp connection interface.  The _aaaa_llll_pppp module returns the function
  77.      address of an interface routine, and fills in a unique identifier (_iiii_dddd)
  78.      for the connection.  The returned function address is NULL on failure
  79.      (and _iiii_dddd is undefined).  This is a sample of making a connection to a
  80.      function managed by _aaaa_llll_pppp:
  81.           _uuuu_nnnn_ssss_iiii_gggg_nnnn_eeee_dddd _cccc_hhhh_aaaa_rrrr _****_nnnn_aaaa_mmmm_eeee_;;;;    _////_**** _aaaa_llll_gggg_oooo_rrrr_iiii_tttt_hhhh_mmmm _nnnn_aaaa_mmmm_eeee _****_////
  82.           _cccc_aaaa_dddd_dddd_rrrr______tttt _iiii_dddd_;;;;             _////_**** _uuuu_nnnn_iiii_qqqq_uuuu_eeee _iiii_dddd _****_////
  83.           _mmmm_bbbb_llll_kkkk______tttt _****_((((_****_ffff_uuuu_nnnn_cccc_))))_((((_))))_;;;;      _////_**** _ffff_uuuu_nnnn_cccc _rrrr_eeee_tttt_uuuu_rrrr_nnnn_ssss _pppp_oooo_iiii_nnnn_tttt_eeee_rrrr _tttt_oooo _mmmm_bbbb_llll_kkkk______tttt _****_////
  84.           _mmmm_bbbb_llll_kkkk______tttt _****_((((_****_aaaa_llll_pppp______cccc_oooo_nnnn_((((_))))_))))_((((_))))_;;;; _////_**** _rrrr_eeee_tttt_uuuu_rrrr_nnnn_ssss _pppp_oooo_iiii_nnnn_tttt_eeee_rrrr _tttt_oooo _mmmm_bbbb_llll_kkkk______tttt _****_////
  85.           _...._...._....
  86.           _iiii_ffff _((((_ffff_uuuu_nnnn_cccc _==== _aaaa_llll_pppp______cccc_oooo_nnnn_((((_nnnn_aaaa_mmmm_eeee_,,,, _((((_cccc_aaaa_dddd_dddd_rrrr______tttt_)))) _&&&&_iiii_dddd_))))_))))
  87.                _r_e_g_u_l_a_r _p_r_o_c_e_s_s_i_n_g_;;;;
  88.           _eeee_llll_ssss_eeee
  89.                _e_r_r_o_r _p_r_o_c_e_s_s_i_n_g_;;;;
  90.      Once the connection has been made, the interface routine can be called
  91.      directly by the connecting module to process messages:
  92.           _mmmm_bbbb_llll_kkkk______tttt _****_iiii_nnnn_pppp_,,,, _****_oooo_uuuu_tttt_pppp_;;;;
  93.           _mmmm_bbbb_llll_kkkk______tttt _****_((((_****_ffff_uuuu_nnnn_cccc_))))_((((_))))_;;;;
  94.           _...._...._....
  95.           _oooo_uuuu_tttt_pppp _==== _((((_****_ffff_uuuu_nnnn_cccc_))))_((((_mmmm_pppp_,,,, _iiii_dddd_))))_;;;;
  96.           _mmmm_pppp _==== _NNNN_UUUU_LLLL_LLLL_;;;;   _////_**** _mmmm_pppp _cccc_aaaa_nnnn_nnnn_oooo_tttt _bbbb_eeee _rrrr_eeee_----_uuuu_ssss_eeee_dddd_!!!! _****_////
  97.           _iiii_ffff _((((_oooo_uuuu_tttt_pppp_))))
  98.                _r_e_g_u_l_a_r _p_r_o_c_e_s_s_i_n_g;
  99.      If the interface routine processed the entire message, then _oooo_uuuu_tttt_pppp is a
  100.      valid pointer to the algorithm's output message.  If, however, the
  101.      routine needs more information, or is buffering something, _oooo_uuuu_tttt_pppp will be a
  102.      null pointer.  In either case, the original message (_mmmm_pppp) may not be
  103.      subsequently accessed by the caller.  The interface routine takes charge
  104.      of the message _mmmm_pppp, and may free it or otherwise dispose of it (it may
  105.      even return the same message).  The caller may pass a null message
  106.      pointer to an interface routine to cause a flush of any data being held
  107.      by the routine; this is useful for end-of-file conditions to insure that
  108.      all data have been passed through.  (Interface routines must thus
  109.      recognize a null message pointer and deal with it.)
  110.  
  111.      Synchronization between input and output messages is not guaranteed for
  112.      all items in the pool.  If one message of input does not produce one
  113.      message of output, this fact should be documented for that particular
  114.      module.  Many multibyte code set conversion algorithms, to cite one
  115.      instance, buffer partial sequences, so that if a multibyte character
  116.      happens to be spread across more than one message, it may take two or
  117.      more output messages to complete translation; in this case, it is only
  118.      possible to synchronize when input message boundaries coincide with
  119.      character boundaries.
  120.  
  121.  
  122.  
  123.  
  124.  
  125.                                                                         PPPPaaaaggggeeee 2222
  126.  
  127.  
  128.  
  129.  
  130.  
  131.  
  132. aaaallllpppp((((7777))))                                                                  aaaallllpppp((((7777))))
  133.  
  134.  
  135.  
  136.    BBBBuuuuiiiillllddddiiiinnnngggg aaaannnn AAAAllllggggoooorrrriiiitttthhhhmmmm ffffoooorrrr tttthhhheeee PPPPoooooooollll
  137.      As mentioned, the modules managed by _aaaa_llll_pppp are implemented as simple
  138.      modules-not STREAMS modules-each with an initialization routine, an open
  139.      routine, and a user-interface routine.  The initialization routine is
  140.      called when the system is booted and prior to nearly everything else that
  141.      happens at boot-time.  The routine takes no arguments and its sole
  142.      purpose is to register the algorithm with the _aaaa_llll_pppp module, so that it may
  143.      subsequently accessed.  Any other required initialization may also be
  144.      performed at that time. A generic initialization routine for a module
  145.      called _GGGG_EEEE_NNNN, with prefix _gggg_eeee_nnnn is as follows:
  146.           _gggg_eeee_nnnn_iiii_nnnn_iiii_tttt_((((_))))
  147.           _{{{{
  148.                _mmmm_bbbb_llll_kkkk______tttt _****_gggg_eeee_nnnn_ffff_uuuu_nnnn_cccc_((((_))))_;;;; _////_**** _iiii_nnnn_tttt_eeee_rrrr_ffff_aaaa_cccc_eeee _rrrr_oooo_uuuu_tttt_iiii_nnnn_eeee _****_////
  149.                _iiii_nnnn_tttt _rrrr_vvvv_aaaa_llll_;;;;          _////_**** _rrrr_eeee_tttt_uuuu_rrrr_nnnn _vvvv_aaaa_llll_uuuu_eeee _ffff_rrrr_oooo_mmmm _rrrr_eeee_gggg_iiii_ssss_tttt_rrrr_aaaa_rrrr _****_////
  150.  
  151.                _rrrr_vvvv_aaaa_llll _==== _aaaa_llll_pppp______rrrr_eeee_gggg_iiii_ssss_tttt_eeee_rrrr_((((_gggg_eeee_nnnn_ffff_uuuu_nnnn_cccc_,,,, _""""_n_a_m_e_""""_,,,, _""""_e_x_p_l_a_n_a_t_i_o_n_""""_))))_;;;;
  152.                _iiii_ffff _((((_rrrr_vvvv_aaaa_llll_)))) _cccc_mmmm_nnnn______eeee_rrrr_rrrr_((((_CCCC_EEEE______WWWW_AAAA_RRRR_NNNN_,,,, _""""_w_a_r_n_i_n_g _m_e_s_s_a_g_e_""""_))))_;;;;
  153.           _}}}}
  154.      The registration routine, _aaaa_llll_pppp______rrrr_eeee_gggg_iiii_ssss_tttt_eeee_rrrr takes three arguments and returns
  155.      zero if successful.  The arguments are (1) a pointer to the algorithm's
  156.      entry point (in this case, the function _gggg_eeee_nnnn_ffff_uuuu_nnnn_cccc), (2) a pointer to its
  157.      name, and (3) a pointer to a character string containing a brief
  158.      explanation.  The name should be limited to under 16 bytes, and the
  159.      explanation to under 60 bytes, as shown in the following example.
  160.      Neither the name nor the explanation need include a newline.
  161.         _iiii _==== _aaaa_llll_pppp______rrrr_eeee_gggg_iiii_ssss_tttt_eeee_rrrr_((((_ssss_jjjj_iiii_ssss_ffff_uuuu_nnnn_cccc_,,,, _""""_ssss_tttt_oooo_uuuu_""""_,,,, _""""_SSSS_hhhh_iiii_ffff_tttt_----_JJJJ_IIII_SSSS _tttt_oooo _UUUU_JJJJ_IIII_SSSS _cccc_oooo_nnnn_vvvv_eeee_rrrr_tttt_eeee_rrrr_""""_))));
  162.      It is possible for a single module to contain several different, related
  163.      algorithms, which can each be registered separately by a single _iiii_nnnn_iiii_tttt
  164.      routine.
  165.  
  166.      A module's open routine is called by _aaaa_llll_pppp______cccc_oooo_nnnn when a connection is first
  167.      requested by a user (that is, a module that wishes to use it).  The open
  168.      routine takes two arguments.  The first argument is an integer; if it is
  169.      non-zero, the request is an open request, and the second argument is
  170.      unused.  The function should allocate a unique identifier and return it
  171.      as a generic address pointer.  If the first argument is zero, the request
  172.      is a close request, and the second argument is the unique identifier that
  173.      was returned by a previous open request, indicating which of (potentially
  174.      several) connections is to be closed.  The routine does any necessary
  175.      clean-up and closes the connection; thereafter, any normal interface
  176.      requests on that identifier will fail.  This use of unique identifiers
  177.      allows these modules to keep state information relating to each open
  178.      connection; no format is imposed upon the unique identifier, so it may
  179.      contain any arbitrary type of information, equivalent in size to a core
  180.      address; _aaaa_llll_pppp and most callers will treat it as being of type _cccc_aaaa_dddd_dddd_rrrr______tttt, in
  181.      a manner similar to the private data held by each instantiation of a
  182.      STREAMS module.
  183.  
  184.  
  185.  
  186.  
  187.                                                                         PPPPaaaaggggeeee 3333
  188.  
  189.  
  190.  
  191.  
  192.  
  193.  
  194. aaaallllpppp((((7777))))                                                                  aaaallllpppp((((7777))))
  195.  
  196.  
  197.  
  198.      A skeleton for the _gggg_eeee_nnnn module's open routine is:
  199.           _gggg_eeee_nnnn_oooo_pppp_eeee_nnnn_((((_aaaa_rrrr_gggg_,,,, _iiii_dddd_))))
  200.                _iiii_nnnn_tttt _aaaa_rrrr_gggg_;;;;
  201.                _cccc_aaaa_dddd_dddd_rrrr______tttt _iiii_dddd_;;;;
  202.           _{{{{
  203.                _iiii_ffff _(((( _aaaa_rrrr_gggg _)))) _{{{{
  204.                     _o_p_e_n _p_r_o_c_e_s_s_i_n_g_;;;;
  205.                     _rrrr_eeee_tttt_uuuu_rrrr_nnnn_(((( _u_n_i_q_u_e-_i_d _))))_;;;;
  206.                _}}}}
  207.                _c_l_o_s_e _p_r_o_c_e_s_s_i_n_g _f_o_r _iiii_dddd_;;;;
  208.                _rrrr_eeee_tttt_uuuu_rrrr_nnnn_((((_0000_))))_;;;;
  209.           }
  210.      Once a connection has been made, users may proceed as in the example in
  211.      the previous section.  When the connection is to be closed (for example,
  212.      the connecting module is being popped), a call is made to _aaaa_llll_pppp______dddd_iiii_ssss_cccc_oooo_nnnn,
  213.      passing the unique id and the name:
  214.           _cccc_aaaa_dddd_dddd_rrrr______tttt _iiii_dddd_;;;;
  215.           _cccc_hhhh_aaaa_rrrr _****_nnnn_aaaa_mmmm_eeee_;;;;
  216.           _mmmm_bbbb_llll_kkkk______tttt _****_aaaa_llll_pppp______dddd_iiii_ssss_cccc_oooo_nnnn_((((_))))_,,,, _****_mmmm_pppp_;;;;
  217.           _...._...._....
  218.           _mmmm_pppp _==== _aaaa_llll_pppp______dddd_iiii_ssss_cccc_oooo_nnnn_((((_nnnn_aaaa_mmmm_eeee_,,,, _iiii_dddd_))))_;;;;
  219.           _iiii_ffff _((((_mmmm_pppp_))))
  220.                _p_r_o_c_e_s_s ``_l_e_f_t-_o_v_e_r'' _d_a_t_a_;;;;
  221.  
  222.      If the disconnect request returns a valid message pointer (_mmmm_pppp) then there
  223.      was unprocessed or partially processed data left in an internal buffer,
  224.      and it should be dealt with by the caller (for example, by flushing it or
  225.      sending it to the neighboring module).
  226.  
  227.    TTTThhhheeee iiiiooooccccttttllll aaaannnndddd QQQQuuuueeeerrrryyyy IIIInnnntttteeeerrrrffffaaaacccceeeessss
  228.      A kernel-level query interface is provided in addition to the query
  229.      interface supported by the _aaaa_llll_pppp_qqqq command.  The routine _aaaa_llll_pppp______qqqq_uuuu_eeee_rrrr_yyyy takes a
  230.      single argument, a pointer to a _n_a_m_e.  If the name matches a registered
  231.      function, _aaaa_llll_pppp______qqqq_uuuu_eeee_rrrr_yyyy returns a pointer to the function's _e_x_p_l_a_n_a_t_i_o_n
  232.      string, otherwise it returns a null pointer.  A calling example is:
  233.           _uuuu_nnnn_ssss_iiii_gggg_nnnn_eeee_dddd _cccc_hhhh_aaaa_rrrr _****_aaaa_llll_pppp______qqqq_uuuu_eeee_rrrr_yyyy_((((_))))_,,,, _****_nnnn_aaaa_mmmm_eeee_,,,, _****_eeee_xxxx_pppp_llll_;;;;
  234.           _...._...._....
  235.           _iiii_ffff _((((_eeee_xxxx_pppp_llll _==== _aaaa_llll_pppp______qqqq_uuuu_eeee_rrrr_yyyy_((((_nnnn_aaaa_mmmm_eeee_))))_))))
  236.                _r_e_g_u_l_a_r _p_r_o_c_e_s_s_i_n_g_;;;;
  237.           _eeee_llll_ssss_eeee
  238.                _e_r_r_o_r _p_r_o_c_e_s_s_i_n_g_;;;;
  239.      The _iiii_oooo_cccc_tttt_llll interface provides calls for querying registered functions (for
  240.      which the _e_x_p_l_a_n_a_t_i_o_n discussed above is necessary); this is supported by
  241.      the _aaaa_llll_pppp_qqqq command, which may be used whenever user-level programs need the
  242.      associated information.
  243.  
  244.  
  245.  
  246.  
  247.                                                                         PPPPaaaaggggeeee 4444
  248.  
  249.  
  250.  
  251.  
  252.  
  253.  
  254. aaaallllpppp((((7777))))                                                                  aaaallllpppp((((7777))))
  255.  
  256.  
  257.  
  258.    UUUUsssseeeessss
  259.      The _aaaa_llll_pppp module can be used to replace various kernel-resident code set
  260.      conversion functions in international or multi-language environments.
  261.      The KBD subsystem (which supplies code set conversion and keyboard
  262.      mapping) supports the use of _aaaa_llll_pppp algorithms as processing elements.
  263.  
  264.      Since state information may be maintained, functions may also implement
  265.      processing on larger or more structured data elements, such as
  266.      transaction records and network packets.  Currently, STREAMS CPU priority
  267.      is assumed by _aaaa_llll_pppp or should be set individually by interface and open
  268.      routines.
  269.  
  270.  
  271.  
  272.  
  273.  
  274.  
  275.  
  276.  
  277.  
  278.  
  279.  
  280.  
  281.  
  282.  
  283.  
  284.  
  285.  
  286.  
  287.  
  288.  
  289.  
  290.  
  291.  
  292.  
  293.  
  294.  
  295.  
  296.  
  297.  
  298.  
  299.  
  300.  
  301.  
  302.  
  303.  
  304.  
  305.  
  306.  
  307.  
  308.  
  309.  
  310.  
  311.  
  312.  
  313.                                                                         PPPPaaaaggggeeee 5555
  314.  
  315.  
  316.  
  317.  
  318.  
  319.  
  320. aaaallllpppp((((7777))))                                                                  aaaallllpppp((((7777))))
  321.  
  322.  
  323.  
  324. EEEEXXXXAAAAMMMMPPPPLLLLEEEESSSS
  325.      /*
  326.       * This is a SAMPLE module that registers with ALP and performs
  327.       * a one-message delay.
  328.       */
  329.      #include <sys/types.h>
  330.      #include <sys/stream.h>
  331.      #include <sys/stropts.h>
  332.      #include <sys/kmem.h>
  333.      #include <sys/alp.h>
  334.  
  335.      static mblk_t *dely();
  336.      caddr_t delyopen();
  337.  
  338.      /*
  339.       * Our state structure.  Keeps its own address and a pointer.
  340.       */
  341.      struct dstruct {
  342.           caddr_t d_unique;
  343.           mblk_t *d_mp;
  344.      };
  345.  
  346.      /*
  347.       * The name is "Dely".  It has an open routine "delyopen"
  348.       * and an interface "dely".
  349.       */
  350.      static struct algo delyalgo =
  351.      {
  352.           0, (queue_t *) 0, (queue_t *) 0, dely, delyopen,
  353.           (unsigned char *) "Dely",
  354.           (unsigned char *) "One Message Delay Buffer",
  355.           (struct algo *) 0
  356.      };
  357.  
  358.      /*
  359.       * This is the sysinit routine, called when the system is
  360.       * being brought up.  It registers "Dely" with ALP.
  361.       */
  362.      delyinit()
  363.      {
  364.           if (alp_register(&delyalgo))  /* then register with ALP */
  365.                printf("DELY: register failed\n");
  366.      }
  367.      /*
  368.       * This is the interface routine itself.
  369.       * Holds onto "mp" and returns whatever it had before.
  370.       */
  371.      static mblk_t *
  372.      dely(mp, id)
  373.           mblk_t *mp;
  374.           caddr_t id;
  375.      {
  376.  
  377.  
  378.  
  379.                                                                         PPPPaaaaggggeeee 6666
  380.  
  381.  
  382.  
  383.  
  384.  
  385.  
  386. aaaallllpppp((((7777))))                                                                  aaaallllpppp((((7777))))
  387.  
  388.  
  389.  
  390.          register mblk_t *rp;
  391.           register struct dstruct *d;
  392.  
  393.           d = (struct dstruct *) id;    /* clarify the situation */
  394.           rp = d->d_mp;
  395.           d->d_mp = mp;
  396.           return(rp);         /* return the previous message */
  397.      }
  398.  
  399.      /*
  400.       * The open (and close) routine.  Use kmem_alloc() to get a private
  401.       * structure for saving state info.
  402.       */
  403.      caddr_t
  404.      delyopen(arg, id)
  405.           int arg;  /* 1 = open, 0 = close */
  406.           caddr_t id;    /* ignored on open; is unique id on close */
  407.      {
  408.           register struct dstruct *d;
  409.           register mblk_t *rp;
  410.  
  411.           if (! arg) {   /* close processing */
  412.                d = (struct dstruct *) id;
  413.                d->d_unique = (caddr_t) -1;
  414.                rp = d->d_mp;
  415.                kmem_free(d, sizeof(struct dstruct));
  416.                return((caddr_t) rp);
  417.           }
  418.           /* otherwise, open processing */
  419.           d = (struct dstruct *) kmem_zalloc(sizeof(struct dstruct),
  420.                      KM_NOSLEEP);
  421.           d->d_unique = (caddr_t) &d;
  422.           return((caddr_t) d);
  423.      }
  424.  
  425. SSSSEEEEEEEE AAAALLLLSSSSOOOO
  426.      _aaaa_llll_pppp_qqqq(1), _kkkk_bbbb_dddd(7).
  427.  
  428.  
  429.  
  430.  
  431.  
  432.  
  433.  
  434.  
  435.  
  436.  
  437.  
  438.  
  439.  
  440.  
  441.  
  442.  
  443.  
  444.  
  445.                                                                         PPPPaaaaggggeeee 7777
  446.  
  447.  
  448.  
  449.